/*
 * @Descripttion: 
 * @version: 
 * @Author: wtzhang
 * @Date: 2021-06-03 15:24:17
 * @LastEditors: wtzhang
 * @LastEditTime: 2021-06-03 16:56:05
 */
// es5的定义方式
/**
 * function Person() {
  this.name = name;
  this.age = age;
  this.run = function () {
    console.log(this.name + '在运动');
  }
}
 */  
// ts类的定义
// class Person {
//   name: string; // 属性 省略了前面的 public 的关键字
//   constructor(name: string) { // 构造函数  就是实例化类的时候触发的方法
//     this.name = name
//   }
//   run(): void {
//     console.log(this.name + '在学习');
//   }
// }
// // 实例化
// let p = new Person('jack')
// p.run() // jack在学习
// > es5 代码 等价于 class 创建的类

class Person {
  public name: string;
  constructor(name: string) {
    this.name = name
  }
  getName():string {
    return this.name
  }
  setName(name:string):void {
    this.name = name
  }
}
let p = new Person('jack')
console.log(p.getName()); // jack
p.setName('rose')
console.log(p.getName()); // rose

console.log('+++++++++++++++++++++++++++');

// ts中类的继承 extends super
class Person1 {
  name: string;
  constructor(name: string) {
    this.name = name
  }
  run():string {
    return`${this.name}在运动🏃`;
  }
}
let p1 = new Person1('jack')
console.log(p1.run()); // jack在运动🏃

// 继承
class User extends Person1 {
  constructor(name: string) {
    super(name)
  }
  // 不仅可以继承 父类的 方法，你也可以扩展自己的 方法
  work(): void {
    console.log(`${this.name}在工作`);
    
  }
}
let u = new User('rose')
console.log(u.run()); // rose在运动🏃
console.log(u.work()); // rose在工作
// > 不仅可以继承 父类的 方法，你也可以扩展自己的 方法

console.log('++++++++++++++继承后 父类，子类有同一个方法+++++++++++++');

class Father {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  run(): string {
    return `${this.name}在运动🏃-父类中的方法`
  }
}
// 继承
class Son extends Father {
  constructor(name: string) {
    super(name)
  }
  run(): string {
    return `${this.name}在运动-子类中的方法`
  }
}
let s = new Son('jack')
console.log(s.run()); // jack在运动-子类中的方法
// > 继承的时候，父类跟子类有同样的方法，继承者执行的方法就是 子类里面的方法


console.log('+++++++++++++类里面的修饰符++++++++++++++++++');

// > 类里面的修饰符，typescript里面定义属性的时候给我们提供了 三种修饰符
/**
 * 修饰符 | 功能特点
 * -- |:-- 
 * public | 公有  在类里面，子类，类外面都可以访问
 * protected | 保护类型  在类里面，子类可以访问，类外面无法访问
 * private | 私有   在类里面可以访问，子类，类外面无法访问
 */

// > 属性不加修饰符，默认公有

// 父类
class User2 {
  public name: string; // 公有属性
  constructor(name: string) {
    this.name = name;
  }
  run(): string {
    return `${this.name}在运动🏃`
  }
}
// 子类
class Son2 extends User2 {
  constructor(name: string) {
    super(name)
  }
}
let s2 = new Son2('jack')
console.log(s2.name); // jack
// > 可以访问

// class User2 {
//   protected name: string; // 保护属性
//   constructor(name: string) {
//     this.name = name;
//   }
//   run(): string {
//     return `${this.name}在运动🏃`
//   }
// }

// // 子类
// class Son2 extends User2 {
//   constructor(name: string) {
//     super(name)
//   }
// }
// let s2 = new Son2('jack')
// console.log(s2.name); 
// > 可以访问


// class User2 {
//   private name: string; // 保护属性
//   constructor(name: string) {
//     this.name = name;
//   }
//   run(): string {
//     return `${this.name}在运动🏃`
//   }
// }

// // 子类
// class Son2 extends User2 {
//   constructor(name: string) {
//     super(name)
//   }
// }
// let s2 = new Son2('jack')
// console.log(s2.name); 
// // > 可以访问
